import os
import pandas as pd
import shutil
import tkinter as tk
from tkinter import filedialog, messagebox, ttk

#  批量图片重命名工具v1.0.0
#  by纱雾
class RenamingApp:
    def __init__(self, root):
        self.root = root
        self.root.title("依据Excel表格中的数据,批量图片重命名工具v1.0.0  by 纱雾")
        self.root.geometry("900x900")

        # 初始化变量
        self.excel_path = tk.StringVar()
        self.image_directory = tk.StringVar()
        self.output_directory = tk.StringVar()
        self.rename_pattern = tk.StringVar(value="{列值}-{列名}")
        self.selected_columns = []  # 用户选择的列名
        self.delete_original_files = tk.BooleanVar(value=False)  # 删除原始文件的选项
        self.df = None  # 保存读取的Excel数据
        self.column_for_image_name = tk.StringVar()  # 保存选择用于命名图片的列

        # 标题
        tk.Label(root, text="依据Excel表格中的数据,批量图片重命名", font=("Arial", 16)).pack(pady=10)

        # 文件选择区
        self.create_file_selection()

        # 重命名规则区
        self.create_rename_rule()

        # 数据表格区
        self.create_table_preview()

        # 操作按钮区
        self.create_action_buttons()

    def create_file_selection(self):
        frame = tk.Frame(self.root)
        frame.pack(pady=10, fill=tk.X, padx=20)

        # Excel 文件选择
        tk.Label(frame, text="选择 Excel 文件:").grid(row=0, column=0, sticky="w")
        tk.Entry(frame, textvariable=self.excel_path, width=50).grid(row=0, column=1)
        tk.Button(frame, text="浏览", command=self.select_excel).grid(row=0, column=2)

        # 图片文件夹选择
        tk.Label(frame, text="图片文件夹:").grid(row=1, column=0, sticky="w")
        tk.Entry(frame, textvariable=self.image_directory, width=50).grid(row=1, column=1)
        tk.Button(frame, text="浏览", command=self.select_image_folder).grid(row=1, column=2)

        # 输出文件夹选择
        tk.Label(frame, text="输出文件夹:").grid(row=2, column=0, sticky="w")
        tk.Entry(frame, textvariable=self.output_directory, width=50).grid(row=2, column=1)
        tk.Button(frame, text="浏览", command=self.select_output_folder).grid(row=2, column=2)

    def create_rename_rule(self):
        frame = tk.Frame(self.root)
        frame.pack(pady=10, fill=tk.X, padx=20)

        # 重命名规则输入
        # 没有太完善!!!!
        tk.Label(frame, text="重命名规则（如 {列值}-{列名}）:").grid(row=0, column=0, sticky="w")
        tk.Entry(frame, textvariable=self.rename_pattern, width=50).grid(row=0, column=1)
        tk.Label(
            frame,
            text="支持的占位符：{列值}, {列名},    重命名规则的功能没有太完善!!!\n现在主要就是你在下方选择什么,他就会显示哪些信息",
            font=("Arial", 10),
            fg="gray",
        ).grid(row=1, column=0, columnspan=2, sticky="w")

        # 删除原始文件选项，确保默认值为False
        self.delete_original_files.set(False)  # 默认不删除源文件
        tk.Checkbutton(
            frame,
            text="删除原始文件",
            variable=self.delete_original_files,
            onvalue=True,
            offvalue=False,
        ).grid(row=2, column=0, columnspan=2, sticky="w")

    def create_table_preview(self):
        frame = tk.Frame(self.root)
        frame.pack(pady=10, fill=tk.BOTH, expand=True, padx=20)

        # 表格标题
        tk.Label(frame, text="Excel 数据预览:").pack(anchor="w")

        # 表格区域
        self.table = ttk.Treeview(frame, show="headings", height=10)
        self.table.pack(fill=tk.BOTH, expand=True)

        # 滚动条
        scrollbar = ttk.Scrollbar(frame, orient="vertical", command=self.table.yview)
        self.table.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side="right", fill="y")

    def create_action_buttons(self):
        frame = tk.Frame(self.root)
        frame.pack(pady=10)

        tk.Button(frame, text="加载数据", command=self.load_excel_data).pack(side="left", padx=5)
        tk.Button(frame, text="开始重命名", command=self.start_renaming).pack(side="left", padx=5)

    def select_excel(self):
        file_path = filedialog.askopenfilename(
            filetypes=[("Excel 文件", "*.xls *.xlsx")],
            title="选择 Excel 文件"
        )
        if file_path:
            self.excel_path.set(file_path)
            # 自动加载Excel数据
            self.load_excel_data()

    def select_image_folder(self):
        folder_path = filedialog.askdirectory(title="选择图片文件夹")
        if folder_path:
            self.image_directory.set(folder_path)

    def select_output_folder(self):
        folder_path = filedialog.askdirectory(title="选择输出文件夹")
        if folder_path:
            self.output_directory.set(folder_path)

    def load_excel_data(self):
        try:
            file_path = self.excel_path.get()
            if not file_path:
                raise FileNotFoundError("未选择 Excel 文件！")
            self.df = pd.read_excel(file_path)

            # 清空表格数据
            for item in self.table.get_children():
                self.table.delete(item)

            # 更新表格列标题
            columns = list(self.df.columns)
            self.table["columns"] = columns
            for col in columns:
                self.table.heading(col, text=col)
                self.table.column(col, width=150, anchor="center")

            # 插入新数据
            for idx, row in self.df.iterrows():
                self.table.insert("", "end", iid=idx, values=list(row))

            # 清除之前的列选择框
            if hasattr(self, 'column_checkbuttons_frame'):
                self.column_checkbuttons_frame.pack_forget()

            # 创建复选框区域
            self.create_column_selection(columns)

            # 添加一个下拉框来选择图片文件名对应的 Excel 列
            self.create_image_name_column_selection(columns)

        except Exception as e:
            messagebox.showerror("错误", str(e))

    def create_column_selection(self, columns):
        # 创建一个框架来显示复选框
        self.column_checkbuttons_frame = tk.Frame(self.root)
        self.column_checkbuttons_frame.pack(pady=10, fill=tk.X, padx=20)

        # 添加标题/提示信息
        tk.Label(self.column_checkbuttons_frame, text="选择你希望参与重命名的 Excel 列: (勾选后列会参与命名)", font=("Arial", 10), fg="gray").pack(anchor="w")

        # 为每一列添加复选框
        self.column_checkbuttons = {}
        for col in columns:
            var = tk.BooleanVar(value=False)
            cb = tk.Checkbutton(self.column_checkbuttons_frame, text=col, variable=var)
            cb.pack(side="left", padx=5)
            self.column_checkbuttons[col] = var


    def create_image_name_column_selection(self, columns):
        frame = tk.Frame(self.root)
        frame.pack(pady=10, fill=tk.X, padx=20)

        tk.Label(frame, text="选择图片文件名对应的 Excel 列:").grid(row=0, column=0, sticky="w")

        # 下拉框选择列
        column_choices = columns
        column_choices.append("无选择")  # 让用户选择不使用Excel数据中的列
        column_menu = ttk.Combobox(frame, textvariable=self.column_for_image_name, values=column_choices, state="readonly", width=50)
        column_menu.set("无选择")
        column_menu.grid(row=0, column=1)

    def start_renaming(self):
        try:
            image_dir = self.image_directory.get()
            output_dir = self.output_directory.get()
            rename_pattern = self.rename_pattern.get()

            if not image_dir or not output_dir:
                raise FileNotFoundError("请确保图片文件夹和输出文件夹已选择！")

            if not rename_pattern:
                raise ValueError("请提供有效的重命名规则！")

            supported_formats = ['.jpeg', '.jpg', '.png']
            os.makedirs(output_dir, exist_ok=True)

            renamed_count = 0
            deleted_count = 0  # 记录删除的文件数

            # 获取删除原始文件的选项
            delete_original_files = self.delete_original_files.get()

            # 获取用户选择的列
            selected_columns = [col for col, var in self.column_checkbuttons.items() if var.get()]

            if not selected_columns:
                raise ValueError("请至少选择一列进行处理！")

            # 获取选择的图片文件名列
            image_name_column = self.column_for_image_name.get()

            if image_name_column == "无选择":
                raise ValueError("请至少选择一列作为图片文件名！")

            for _, row in self.df.iterrows():
                # 拼接多列数据
                new_file_name = ""
                for col in selected_columns:
                    new_file_name += f"{row[col]}-"

                # 去掉多余的分隔符
                new_file_name = new_file_name.rstrip("-")

                # 查找匹配的图片文件
                for file in os.listdir(image_dir):
                    file_name, file_extension = os.path.splitext(file)
                    if file_extension.lower() in supported_formats and row[image_name_column] in file_name:
                        old_file_path = os.path.join(image_dir, file)
                        new_file_path = os.path.join(output_dir, new_file_name + file_extension)

                        # 输出匹配到的文件信息
                        print(f"匹配文件: {file} -> 新文件名: {new_file_name + file_extension}")
                        print(f"源文件路径: {old_file_path} -> 目标文件路径: {new_file_path}")

                        # 将文件从原目录复制到输出目录并重命名（保持原始文件夹不变）
                        if old_file_path != new_file_path:
                            shutil.copy2(old_file_path, new_file_path)  # 使用 copy2 保留文件的元数据
                            renamed_count += 1

                        # 只有勾选删除原始文件时，才执行删除操作
                        if delete_original_files:
                            try:
                                os.remove(old_file_path)  # 删除源文件
                                deleted_count += 1
                            except Exception as e:
                                print(f"删除源文件失败: {e}")

            messagebox.showinfo("完成", f"批量重命名完成！共处理 {renamed_count} 个文件，删除了 {deleted_count} 个原始文件。")
        except Exception as e:
            messagebox.showerror("错误", str(e))

def show_welcome_message():
    welcome_msg = """欢迎使用图片批量重命名工具！\n\n
本程序可以帮助你根据 Excel 表格中的数据，\n
按列批量重命名指定文件夹中的图片。\n\n
操作步骤：\n1. 选择 Excel 文件，\n2. 选择图片文件夹，\n
3. 设置重命名规则，\n4. 点击“开始重命名”按钮即可。\n\n
现在可能会遇到的问题：\n1.重命名规则没有咋搞好,可能下一个版本能优化一下\n2.可能还会有一些小的bug点没有测试出来,大家可以多我反馈一下!\n\n
反馈地址:\n微信公众号:㫪Spring\nQQ:755508842\n\n

by 纱雾\n\n
"""
    messagebox.showinfo("欢迎使用", welcome_msg)

if __name__ == "__main__":
    # 在启动时显示欢迎消息
    show_welcome_message()

    # 创建根窗口
    root = tk.Tk()

    # 在弹窗后确保主窗口显示在前台
    root.after(100, root.deiconify)
    root.lift()

    app = RenamingApp(root)
    root.mainloop()
